package com.icloud.wallet.boot.schedule;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.icloud.common.database.enums.TaskCodeEnum;
import com.icloud.common.web.enums.StateEnum;
import com.icloud.wallet.boot.mapper.TSysCronMapper;
import com.icloud.wallet.boot.model.TSysCron;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.Trigger;
import org.springframework.scheduling.TriggerContext;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;
import org.springframework.scheduling.support.CronTrigger;

import java.util.Date;
import java.util.List;
import java.util.Objects;

@Slf4j
@Configuration
@EnableScheduling
public class ScheduleTaskConfig implements SchedulingConfigurer {
    @Autowired
    private TSysCronMapper tSysCronMapper;
    @Autowired
    private CalWithdrawableTask calWithdrawableTask;
    @Autowired
    private CollectTask collectTask;
    @Autowired
    private RedPacketTask redPacketTask;
    @Override
    public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
        LambdaQueryWrapper<TSysCron> cronQuery = new LambdaQueryWrapper<>();
        cronQuery.eq(TSysCron::getState, StateEnum.NORMAL.getCode());
        cronQuery.isNotNull(TSysCron::getCron);
        List<TSysCron> cronList = tSysCronMapper.selectList(cronQuery);
        cronList.forEach(cronTask->{
            String code = cronTask.getTaskCode();
            TaskCodeEnum taskCodeEnum = TaskCodeEnum.byCode(code);
            taskRegistrar.addTriggerTask(() -> {
                switch (Objects.requireNonNull(taskCodeEnum)){
                    case CAL_WITHDRAWABLE:
                        calWithdrawableTask.run();
                        break;
                    case AUTO_COLLECT:
                        log.info("AUTO_COLLECT");
                        collectTask.collect();
                        break;
                    case REFUND_RED_PKT:
                        log.info("REFUND_RED_PKT");
                        redPacketTask.refund();
                        break;
                }
            }, new Trigger() {
                @Override
                public Date nextExecutionTime(TriggerContext triggerContext) {
                    cronQuery.clear();
                    cronQuery.eq(TSysCron::getTaskCode, code);
                    cronQuery.eq(TSysCron::getState, StateEnum.NORMAL.getCode());
                    cronQuery.isNotNull(TSysCron::getCron);
                    TSysCron tSysCron = tSysCronMapper.selectOne(cronQuery);
                    String nextCron = tSysCron.getCron();
                    CronTrigger trigger = new CronTrigger(nextCron);
                    return trigger.nextExecutionTime(triggerContext);
                }
            });
        });
    }
}
